package ro.pub.cs.hwchecker.login.client;

import ro.pub.cs.hwchecker.comm.client.data.LoginCredentials;
import ro.pub.cs.hwchecker.comm.client.json.JSONLoginRequestBuilder;
import ro.pub.cs.hwchecker.comm.client.req.CheckerCallback;
import ro.pub.cs.hwchecker.comm.client.req.CheckerRequest;
import ro.pub.cs.hwchecker.comm.client.req.CheckerRequestException;
import ro.pub.cs.hwchecker.comm.client.req.LoginRequestBuilder;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTMLTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HorizontalPanel;


public class LoginForm extends VerticalPanel implements ClickListener, CheckerCallback<Void>
{
	private static final String panelStyleName = "hwcheckerLoginPanel"; 
	private static final String titleStyleName = "loginTitle"; 
	private static final String titleImgStyleName = "loginTitleImg"; 
	private static final String labelStyleName = "loginLabel";
	private static final String textboxStyleName = "loginTextbox";
	private static final String buttonStyleName = "loginButton";
	private static final String msgStyleName = "loginMsg";
	
	private static final String errorMsgStyleName = "error";
	private static final String normalMsgStyleName = "normal";
	
	private static final TextBox usernameTextBox = new TextBox(); 
	private static final PasswordTextBox passwordTextBox = new PasswordTextBox(); 
	private static final Button loginButton = new Button(); 
	private static final Label msgLabel = new Label();  
	
	public LoginForm()
	{
		super(); 
		this.setStylePrimaryName(panelStyleName);
		/* the title */ 
		HorizontalPanel title = new HorizontalPanel(); 
		title.setStylePrimaryName(titleStyleName);
		Label titleLogo = new Label();
		titleLogo.setStylePrimaryName(titleImgStyleName);
		title.add(titleLogo); 
		this.add(title); 
		/* the form */ 
		Grid g = new Grid(3, 2);
		HTMLTable.CellFormatter cf = g.getCellFormatter();
		Label usernameLabel = new Label();
		usernameLabel.setText("username");
		usernameLabel.setStylePrimaryName(labelStyleName); 
		g.setWidget(0, 0, usernameLabel);
		cf.setHorizontalAlignment(0, 0, HasHorizontalAlignment.ALIGN_CENTER);
		usernameTextBox.setStylePrimaryName(textboxStyleName); 
		g.setWidget(0, 1, usernameTextBox);
		Label passwordLabel = new Label();
		passwordLabel.setText("password");
		passwordLabel.setStylePrimaryName(labelStyleName); 
		g.setWidget(1, 0, passwordLabel);
		cf.setHorizontalAlignment(1, 0, HasHorizontalAlignment.ALIGN_CENTER);
		passwordTextBox.setStylePrimaryName(textboxStyleName); 
		g.setWidget(1, 1, passwordTextBox);
		/* the submit button */ 
		loginButton.addClickListener(this); 
		loginButton.setStylePrimaryName(buttonStyleName);
		loginButton.setText("Login");
		g.setWidget(2, 0, loginButton);
		cf.setVerticalAlignment(2, 0, HasVerticalAlignment.ALIGN_TOP); 
		cf.setHorizontalAlignment(2, 0, HasHorizontalAlignment.ALIGN_CENTER);
		/* the message bar */ 
		msgLabel.setStylePrimaryName(msgStyleName); 
		this.add(msgLabel); 
		g.setWidget(2, 1, msgLabel); 
		cf.setVerticalAlignment(2, 1, HasVerticalAlignment.ALIGN_TOP); 
		cf.setHorizontalAlignment(2, 1, HasHorizontalAlignment.ALIGN_LEFT);
		/* add the grid */ 
		this.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
		this.add(g);
	}
	
	private boolean validation()
	{
		if ((usernameTextBox.getText().length() == 0) ||
			(passwordTextBox.getText().length() == 0))
			return false;
		return true;
	}
	
	private static void showMsg(String msg, String style)
	{
		/* flush styles */ 
		msgLabel.setStyleName(msgLabel.getStylePrimaryName());
		/* add the specific style name */ 
		msgLabel.addStyleName(style);
		/* show text */ 
		msgLabel.setText(msg); 
	}
	
	public void onClick(Widget sender) 
	{
		if (validation())
		{
			/* Do not permit further requests */
			loginButton.setEnabled(false);
			LoginRequestBuilder loginReq = new JSONLoginRequestBuilder();
			/* Show visual progress */
			showMsg("Loading...", normalMsgStyleName); 			
			
			try {
				loginReq.performLogin(
						new LoginCredentials(
								usernameTextBox.getText(),
								passwordTextBox.getText()), 
						this);
			} catch (CheckerRequestException ex) {
				onCheckerError(null, ex);
			}
		}
		else
		{
			showMsg("Input data is invalid", errorMsgStyleName); 
		}
	}
	
	public void onCheckerError(CheckerRequest req, CheckerRequestException error) 
	{
	 	showMsg("Server error: " + error.getMessage(),
	 			errorMsgStyleName);
		loginButton.setEnabled(true);
	}

	public void onCheckerResponse(CheckerRequest req, Void v) 
	{
		Window.Location.replace(GWT.getHostPageBaseURL() + "app");
	}
	
}

